<?php
namespace App\Http\Services;

use Carbon\Carbon;
use App\Http\Model\CrossRoomPkRecord;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use App\Lib\Publisher;
use App\Http\Model\Hint;
use App\Http\Model\User;
use App\Http\Model\Mall;
use App\Http\Model\Room;
use App\Http\Model\RoomUser;
use App\Http\Model\FinanceUserWallet;
use App\Http\Model\Gift;
use App\Http\Model\RoomHot;
use App\Http\Model\Union;
use App\Http\Model\UnionUser;
use App\Http\Model\RoomMicro;
use App\Http\Model\RoomHostMicro;
use App\Http\Model\Relation;
use App\Http\Services\RoomMsgServices;
use App\Http\Services\MsgServices;
use App\Http\Services\RoomHotServices;
use App\Http\Services\UserBlacklistServices;
use App\Http\Services\NewRoomMicroServices;

class NewRoomServices extends CommonServices
{
    protected $roomModel;
    protected $roomUserModel;
    protected $financeUserWalletModel;
    protected $giftModel;
    protected $roomHotModel;
    protected $roomMsgService;
    protected $msgService;
    protected $roomHotService;
    protected $model_union_user;//公会用户model
    protected $crossRoomPkModel;//pk发起记录
    protected $model_union;//公会
    protected $roomMicroModel;//普通麦
    protected $roomHostMicroModel;//主持麦
    protected $userBlacklistService;
    protected $newRoomMicroService;
    protected $userModel;
    protected $mallModel;
    protected $relationModel;

    protected $micro_lock_key = "micro";//麦位锁定

    //房间在麦人数不足计数缓存
    protected $roomMicroFailNumKey = 'ROOM:MICROFAILNUM:';//string ROOM:MICROFAILNUM:{roomOpenId} => {num}
    //房间每单位时间热度缓存
    protected $roomMinuteHotNumKey = 'ROOM:MINUTEHOTNUM:';//hash ROOM:MINUTEHOTNUM:{roomOpenId} => {分钟数}=>{num}
    protected $userPkSendMsgKey = 'CROSS:ROOM:PK:MISSION:SENDMSGUSER:';//用户发言每日PK任务; 

    //拍拍房记录缓存
    protected $roomPaiPaiKey = 'ROOMPAIPAI:LOG:';//hash ROOMPAIPAI:LOG:{roomId} => {string}=>{string}
    //拍拍房收礼用户缓存
    protected $roomPaiPaiGetGiftUserKey = 'ROOMPAIPAI:GETGIFTUSER:';//set ROOMPAIPAI:GETGIFTUSER:{logId} => {userId}
    //拍拍房收礼送礼用户排行缓存
    protected $roomPaiPaiUserRankKey = 'ROOMPAIPAI:USERRANK:';//zset ROOMPAIPAI:USERRANK:{logId}:{toUserId} => {积分}=>{fromUserId}
    //拍拍房麦位缓存
    protected $roomPaiPaiMicroKey = 'ROOMPAIPAI:MICRO:';//string ROOMPAIPAI:MICRO:{logId} => {string}

    protected $redis_room = "ROOM:"; //房间热度缓存
    protected $redis_room_cache = 'CACHE:ROOM:';//房间缓存

    public function __construct()
    {
        $this->roomModel = new Room();
        $this->roomUserModel = new RoomUser();
        $this->financeUserWalletModel = new FinanceUserWallet();
        $this->giftModel = new Gift();
        $this->roomHotModel = new RoomHot();
        $this->roomMsgService = new RoomMsgServices();
        $this->msgService = new MsgServices();
        $this->roomHotService = new RoomHotServices();
        $this->userBlacklistService = new UserBlacklistServices();
        $this->newRoomMicroService = new NewRoomMicroServices();
        $this->model_union_user = new UnionUser();
        $this->model_union = new Union();
        $this->crossRoomPkModel = new CrossRoomPkRecord();
        $this->roomMicroModel = new RoomMicro();
        $this->roomHostMicroModel = new RoomHostMicro();
        $this->userModel = new User();
        $this->mallModel = new Mall();
        $this->relationModel = new Relation();

    }

    /**
     * 更新开厅时长
     */
    public function setOnlineTime(){
        $code = Hint::SUCCESS;
        $msg = Hint::getErrCodeMsg($code);
        $data = [];
        $open_room_ids = $this->roomModel->getOpenedRoomIdArr();
        $cbd_room_ids = $this->roomModel->getCbdRoomId();
        $all_room_ids = array_intersect($open_room_ids ,$cbd_room_ids);
        foreach ($all_room_ids as $open_room_id){
            $password = $this->roomModel->get_password($open_room_id);
            if (!empty($password)){
                continue;
            }
            $date = strtotime(date('Y-m-d'));
//            $user_ids = $this->roomUserModel->get_usersids($open_room_id);

            $room = $this->roomModel->get_room($open_room_id);
            $typeId = $room['room_type']['id'];

            $microNum = 0;

            // 普通麦
            $micros = $this->roomMicroModel->get_micros($open_room_id, $typeId); //room type从房间获得。
            for ($i = 0; $i < count($micros); $i++){
                if($micros[$i]["user_id"] !== null){
                    $microNum++;
                }
            }
            // 主持麦
            $hostUserId = $this->roomHostMicroModel->get_user_id($open_room_id);
            if ($hostUserId) {
                $microNum++;
            }

            $more_five_mic_time = 0;
            $less_five_mic_time = 0;
            if($microNum>=5){
                $more_five_mic_time = $this->roomModel->roomOpenTimes;
            }else{
                $less_five_mic_time = $this->roomModel->roomOpenTimes;
            }
            $this->roomModel->setRoomOpenTime($open_room_id ,$date,$this->roomModel->roomOpenTimes,$more_five_mic_time,$less_five_mic_time,time());
        }
        return compact('code', 'msg', 'data');
    }

    /**
     * 更新房间热度和开启时长
     */
    public function setRoomhot(){
        $list = $this->roomModel->getAllRoomOpenList();
        foreach($list as $key=>$val) {
            [$roomId, $type] = explode(':', $key);
            if($type == 'roomOpenId') {
                if(empty($val)) {
                    continue;
                }

                //累加开启时长
                $this->roomModel->incrRoomOpenLog($val, 'open_time_num', 300);

                //根据房间ID更新房间热度
                $this->setRoomhotByRoomId($roomId, $val);
            }
        }
    }

    /**
     * 根据房间ID更新房间热度
     */
    public function setRoomhotByRoomId($roomId, $roomOpenId=0){
        if(empty($roomOpenId)) {
            $roomOpenId = $this->roomModel->getRoomOpenList($roomId, 'roomOpenId');
        }
        if(empty($roomOpenId)) {
            return 0;
        }
        //获取房间开启记录
        $openLog = $this->roomModel->getRoomOpenLog($roomOpenId);
        if(empty($openLog)) {
            return 0;
        }

        //更新开场热度
        $this->updateRoomStartHotNum($roomId, $roomOpenId);

        //更新房间用户热度
        $this->updateRoomUserHotNum($roomId, $roomOpenId);

        //更新房间公屏消息热度
        $this->updateRoomMsgHotNum($roomOpenId);

        //更新房间礼物热度
        $giftHotNum = $this->updateRoomGiftHotNum($openLog);

        //在麦不足扣除热度数
        $this->updateRoomMicroDecr($roomId, $roomOpenId);

        //更新房间礼物衰减热度
        $this->updateRoomGiftDear($openLog, $giftHotNum);

        //更新房间最终热度
        $hotNum = $this->updateRoomHotNum($roomOpenId);

        return $hotNum;
    }
    //更新开场热度
    public function updateRoomStartHotNum($roomId, $roomOpenId)
    {
        //开场热度
        $startHotNum = 0;
        $startHotNumMax = 1000;//开场热度最大值
        $oldList = $this->roomModel->getRoomOpenLogByRoomIdLimitOpentime($roomId, $roomOpenId);
        $oldNum = count($oldList);
        //  - 历史有效直播场次n>7次，取最近7个有效的直播场次产生的直播【最终热度】的平均数
        if($oldNum >= 7) {
            $oldList = array_slice($oldList, 0, 7);
            $startHotNum = intval(array_sum(array_column($oldList, 'hot_num'))/7);
            $startHotNum = ($startHotNum > $startHotNumMax) ? $startHotNumMax : $startHotNum;
        }
        //  - 历史有效直播场次0<n<7次，取最近3个有效的直播场次产生的直播【最终热度】的平均数
        if($oldNum>0 && $oldNum<7) {
            $oldList = array_slice($oldList, 0, 3);
            $startHotNum = intval(array_sum(array_column($oldList, 'hot_num'))/count($oldList));
            $startHotNum = ($startHotNum > $startHotNumMax) ? $startHotNumMax : $startHotNum;
        }
        //  - 历史有效直播场次n=0，取预置厅分数
        if($oldNum == 0) {
            $startHotNum = $this->roomModel->get_recommend($roomId);
        }
        if($startHotNum < 1000){
            $startHotNum = 1000;
        }
        //更新
        $log = [
            'start_hot_num' => $startHotNum,
        ];
        $this->roomModel->updateRoomOpenLog($roomOpenId, $log);
        return $startHotNum;
    }
    //更新房间公屏消息热度
    public function updateRoomMsgHotNum($roomOpenId)
    {
        //聊天条数：每5条一起增加10（非单条增加2），取消公屏发言普通用户与高级用户的逻辑，单日公屏消息最多增加5000热度；
        $msgList = $this->roomModel->getSumRoomUserMsgByRoomOpen($roomOpenId);
        $msgHotNum = intval(($msgList['sms_num_1'] + $msgList['sms_num_2'])/5)*10;
        $msgHotNum = ($msgHotNum>5000) ? 5000 : $msgHotNum;//公屏消息热度
        //更新
        $log = [
            'msg_num' => $msgHotNum,
        ];
        $this->roomModel->updateRoomOpenLog($roomOpenId, $log);
        return $msgHotNum;
    }
    //更新房间用户热度
    public function updateRoomUserHotNum($roomId, $roomOpenId)
    {
        //观看人数 高级用户*2 低级用户*1
        $seeNum = 0;
        $inRoomUserIds = $this->roomUserModel->getRoomUserIdArr($roomId);
        $userWallet = $this->financeUserWalletModel->get_wallets($inRoomUserIds);
        foreach($userWallet as $wallet) {
            //财富等级1 大于等于 1000
            if($wallet['wealth_balance'] >= 1000) {
                $seeNum = $seeNum + 2;
            }else{
                $seeNum = $seeNum + 1;
            }
        }
        $userHotNum = $seeNum;//房间用户热度

        //更新
        $log = [
            'user_num' => $userHotNum,
        ];
        $this->roomModel->updateRoomOpenLog($roomOpenId, $log);

        //MQ通知
        $mqData = [
            'room_id' => $roomId,
            'userIds' => $inRoomUserIds,
        ];
        $this->_mqSendActivity(3, $mqData);

        return $userHotNum;
    }
    //更新房间礼物热度
    public function updateRoomGiftHotNum($openLog)
    {
        //直刷礼物总值*60%（不算背包礼物） 大额直刷礼物奖励分数：单个礼物超过1000钻石以上的（1000钻石可能会调整），在原有的基础上再奖励200分数（200分可能会调整
        $giftNum = 0;
        $giftBigNum = 0;
        $giftList = $this->giftModel->roomStreamSumByTime($openLog['room_id'], strtotime($openLog['created_at']), time());
        foreach($giftList as $gift) {
            if(empty($gift['gift_num'])) {
                continue;
            }
            $giftNum = $giftNum + $gift['gift_num']*$gift['gift_price'];
            if($gift['gift_price'] >= 1000) {
                $giftBigNum = $giftBigNum + $gift['gift_num']*200;
            }
        }
        $giftHotNum = ceil($giftNum*0.6) + $giftBigNum;//礼物总热度

        //热度卡增加的值
        foreach($giftList as $v){
            //获取之前送礼信息
            $hotNum = $this->giftModel->getRoomHotNum($openLog['id'], $v['gift_id']);
            if(!empty($hotNum['total']) && $v['gift_type'] == 10){
                $giftHotNum += $hotNum['total'];
            }
        }

        //更新
        $log = [
            'gift_num' => $giftHotNum,
        ];
        $this->roomModel->updateRoomOpenLog($openLog['id'], $log);
        return $giftHotNum;
    }
    //在麦不足扣除热度数
    public function updateRoomMicroDecr($roomId, $roomOpenId)
    {
        //- 当房间内在麦人数不足5人时（包含主持），每5分钟扣除500热度值；
        $needUserNum = 5;//需要房间人数
        $minute = 5;//间隔分钟
        $decrNum = 500;//每次扣除
        //麦的信息
        $roomMicro = $this->roomHotService->getRoomMicroUser($roomId);
        $cacheKey = $this->roomMicroFailNumKey.$roomOpenId;
        if(count($roomMicro['all']) < $needUserNum) {
            $num = Redis::INCRBY($cacheKey, 1);//计数
            if($num >= $minute) {
                $num = Redis::SET($cacheKey, 0);//还原
                //获取房间原来热度,若热度小于1499不扣除
                $nowHotNum = $this->roomModel->getRoomOpenLog($roomOpenId);;
                if($nowHotNum['hot_num'] <= 1499){
                    $decrNum = 0;
                }
                //在麦不足扣除热度数
                $this->roomModel->incrRoomOpenLog($roomOpenId, 'micro_decr', $decrNum);
            }
        }else{
            $num = Redis::SET($cacheKey, 0);//还原
        }
        Redis::EXPIRE($cacheKey, 86400);

        //MQ通知
        $mqData = [
            'room_id' => $roomId,
            'userIds' => $roomMicro['all'],
        ];
        $this->_mqSendActivity(4, $mqData);
    }
    //更新房间礼物衰减热度
    public function updateRoomGiftDear($openLog, $giftHotNum)
    {
        //礼物衰减热度 每20分钟5% 直到90%
        $minute = 20;
//        $rate = 0.05;
        $rate = 0.2;
        $rateMax = 0.9;

        //房间开启到现在的分钟数
        $nowOpenMinute = intval((time() - strtotime($openLog['created_at']))/60);
        //当前阶段
        $step = ceil($nowOpenMinute/$minute);

        //之前阶段的总值
        $oldGiftHotNum = 0;
        //礼物热度衰减值
        $giftDecr = 0;

        //缓存获取
        $cacheKey = $this->roomMinuteHotNumKey.$openLog['id'];
        $list = Redis::HGETALL($cacheKey);
        foreach($list as $k=>$v) {
            //当前阶段的不累计 不衰减
            if($k == $step) {
                continue;
            }
            //累计之前阶段
            $oldGiftHotNum = $oldGiftHotNum + $v;
            //计算衰减
            $num = $step - $k;
            if($num > 0) {
                $giftDecr = $giftDecr + ($v * min($num*$rate, $rateMax));

            }
        }
        //本阶段的值
        $stepGiftHotNum = $giftHotNum - $oldGiftHotNum;
        $stepGiftHotNum = ($stepGiftHotNum<1) ? 0 : $stepGiftHotNum;
        $hotNum = $openLog['start_hot_num'] + $openLog['msg_num'] + $openLog['user_num'] + $openLog['gift_num'] - $openLog['micro_decr'] - $giftDecr + $openLog['zero_num'];
        //判断是否小于1000
        if($hotNum <= 1000){
//            write_log('giftDecr33','$hotNum',$hotNum);
            $giftDecr = $openLog['gift_decr']+intval(abs($hotNum));//取原来的值
//            write_log('giftDecr33','$hotNum'.$openLog['id'],$hotNum);

        }
        Redis::HSET($cacheKey, $step, $stepGiftHotNum);//记录
        Redis::EXPIRE($cacheKey, 86400);


        //更新
        $log = [
            'gift_decr' => (int) $giftDecr,
        ];
//        write_log('giftDecr222','giftDecrlogs',$log);
        $this->roomModel->updateRoomOpenLog($openLog['id'], $log);
        return $giftDecr;
    }
    //更新房间最终热度
    public function updateRoomHotNum($roomOpenId)
    {
        //最终热度 开场热度+公屏消息热度+房间用户热度+礼物热度-在麦不足扣除热度数-礼物热度衰减+归零补值
        $openLog = $this->roomModel->getRoomOpenLog($roomOpenId);
        $hotNum = $openLog['start_hot_num'] + $openLog['msg_num'] + $openLog['user_num'] + $openLog['gift_num'] - $openLog['micro_decr'] - $openLog['gift_decr'] + $openLog['zero_num'];

        //直刷礼物总值*60%（不算背包礼物） 大额直刷礼物奖励分数：单个礼物超过1000钻石以上的（1000钻石可能会调整），在原有的基础上再奖励200分数（200分可能会调整
        $giftNum = 0;
        $giftBigNum = 0;

        $end_time = time();
        $start_time = $end_time-300;

        $giftList = $this->giftModel->roomStreamSumByTime($openLog['room_id'], $start_time, $end_time);
        foreach($giftList as $gift) {
            if(empty($gift['gift_num'])) {
                continue;
            }
            $giftNum = $giftNum + $gift['gift_num']*$gift['gift_price'];
            if($gift['gift_price'] >= 1000) {
                $giftBigNum = $giftBigNum + $gift['gift_num']*200;
            }
        }

        $giftHotNum = bcadd((bcmul($giftNum, 1)),$giftBigNum);//礼物总热度
        $hotNum = bcadd(bcmul($openLog['hot_num_new'], 0.977), $giftHotNum);

        $startHotNum = $this->roomModel->get_recommend($openLog['room_id']);

        if ($startHotNum > 0) {
            $hotNum = bcadd($hotNum, $startHotNum);
            $this->roomModel->updateRoomCoefficient($openLog['room_id'], 0);
        }
        $hotNum = ($hotNum < 1000) ? 1000 : $hotNum;

        $log = [
            'hot_num_new' => $hotNum,
        ];
        $this->roomModel->updateRoomOpenLog($roomOpenId, $log);

        if($log['hot_num_new'] != $openLog['hot_num_new']) {
            $this->roomMsgService->broadcast_hot_change($openLog['room_id']);
        }

        //归零补值
//        if($hotNum < 0) {
//            //更新
//            $log = [
//                'zero_num' => abs($hotNum),
//            ];
//            $this->roomModel->updateRoomOpenLog($openLog['id'], $log);
//            $hotNum = 0;
//        }
//
//        //如果锁房了归零
//        if ($this->roomModel->get_password($openLog['room_id']) !== null){
//            $hotNum = 0;
//        }
////        $hotNum = ($hotNum < 1) ? 0 : $hotNum;
//        $hotNum = ($hotNum < 1000) ? 1000 : $hotNum;

        //更新
//        $log = [
//            'hot_num' => $hotNum,
//        ];
//        $this->roomModel->updateRoomOpenLog($roomOpenId, $log);

        //缓存
        $this->roomHotModel->set($openLog['room_id'], $hotNum);

        //通知
//        if($log['hot_num'] != $openLog['hot_num']) {
//            $this->roomMsgService->broadcast_hot_change($openLog['room_id']);
//        }

        return $hotNum;
    }


    /**
     * 记录房间用户聊天
     */
    public function saveUserChat($roomId, $userId, $content)
    {
        do {
            if(empty($roomId)) {
                break;
            }
            if(empty($userId)) {
                break;
            }
            //单个用户同一分钟最多贡献五条
            // if (!redis_num_lock('CACHE:OPENROOM:SAVECHAT:'.$userId.':'.$roomId, 60, 5)) {
            //     break;
            // }
            //获取房间开启记录
            $roomOpenId = $this->roomModel->getRoomOpenList($roomId, 'roomOpenId');
            if(empty($roomOpenId)) {
                break;
            }

            //获取用户财富值
            // $userWallet = $this->financeUserWalletModel->get_wallet($userId);
            // $wealthBalance = empty($userWallet['wealth_balance']) ? 0 : $userWallet['wealth_balance'];
            //财富等级1 大于等于 1000
            $field = 'sms_num_1';
            // if($wealthBalance >= 1000) {
                // $field = 'sms_num_2';
            // }

            //跨房PK任务发言
            //文字内容必须大于等于10个字才能完成任务
            $contentLength = strlen(iconv('utf-8', 'utf-16le', $content)) / 2;
            //判断用户是否是主播
            $isanchor = 0;
            $res = $this->model_union_user->userToUnion($userId);
            if(!empty($res)){
                //查看公会是否认证
                $checkStatus = $this->model_union->getUnions([$res['un_id']]);
                if(isset($checkStatus[0]['authentication_status']) && $checkStatus[0]['authentication_status'] != 0){
                    $isanchor = 1;
                }
            }
            //获取房间是否在PK中
            //获取缓存房间模式
            $roomMode = $this->roomModel->getRoomOpenList($roomId, 'roomMode');

            if($contentLength >= 10 && empty(Redis::get($this->userPkSendMsgKey.$userId)) && !empty($isanchor) && $roomMode == 6 ){
                $missList = $this->crossRoomPkModel->getMissionGift();
                $missList = array_column($missList,null,'mission_type');
                $insertMission = [
                    'user_id' => $userId,
                    'mission_type' => 3,//任务类型 1=PK送礼 2=上麦任务 3=发言 4=PK胜利
                    'goods_id' => $missList[3]['goods_id'],
                    'send_status'=> 0,
                    'created_at' => Carbon::now()->toDateTimeString(),
                ];
                $this->crossRoomPkModel->insertMission($insertMission);
                //记录redis
                //计算结束当天所差秒数
                $now = Carbon::now()->toDateTimeString();
                $endDay = Carbon::now()->endOfDay()->toDateTimeString();
                $diffTime = Carbon::parse($now)->diffInSeconds($endDay);
                Redis::SET($this->userPkSendMsgKey.$userId,1);
                Redis::EXPIRE($this->userPkSendMsgKey.$userId,$diffTime);//当天结束时间秒数
            }else{
                write_log('cross_room_pk_send_msg','ERROR 不满足条件',['length'=>$contentLength,'isSend'=>Redis::get($this->userPkSendMsgKey.$userId),'isanchor'=>$isanchor,'roomModel'=>$roomMode]);
            }

            //是否存在
            $info = $this->roomModel->getRoomUserMsgByUserRoomOpen($roomOpenId, $userId);
            if(empty($info)) {
                $data = [
                    'room_id' => $roomId,
                    'room_open_id' => $roomOpenId,
                    'user_id' => $userId,
                ];
                $id = $this->roomModel->createRoomUserMsg($data);
            }else{
                $id = $info['id'];
            }
            //累加
            $this->roomModel->incrRoomUserMsg($id, $field, 1);

            //MQ通知
            $mqData = [
                'user_id' => $userId,
                'room_id' => $roomId,
            ];
            $this->_mqSendActivity(2, $mqData);

            //记录内容
            $this->userBlacklistService->checkSaveUserMsg($userId, $content, 0, $roomId, 1);

        } while (false);
    }

    //MQ通知
    protected function _mqSendActivity($type, $mqData) {
        try {
            $requestData = [
                'queue_route' => 'global.activity',
                'data' => [
                    'mqtype' => $type,
                    'mqData' => $mqData,
                    'create' => time()
                ],
            ];

            $publishObject = Publisher::getInstance();
            $publishObject->requestData = $requestData;
            $publishObject->publisher();
        } catch (\Exception $e) {
            write_log('error_mq', 'global.activity', ['requestData'=>$requestData]);
        }
    }

    /**
     * 新增置顶房间
     */
    public function topRoomCreate($roomId, $sortNum, $timeSt, $timeEd)
    {
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        do {
            if(empty($roomId)) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            //是否存在
            $info = $this->roomModel->getRoomTop($roomId);
            if(!empty($info)) {
                $code = Hint::PARAM_ERROR;
                $msg = '房间现在已经配置了置顶,请删除后添加';
                break;
            }
            $cData = [
                'room_id' => $roomId,
                'sort_num' => $sortNum,
                'time_st' => $timeSt,
                'time_ed' => $timeEd,
            ];
            $id = $this->roomModel->createRoomTop($cData);

        } while (false);
        return compact('code', 'msg', 'data');
    }

    /**
     * 修改置顶房间
     */
    public function topRoomUpdate($roomId, $sortNum, $timeSt, $timeEd)
    {
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        do {
            if(empty($roomId)) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            //是否存在
            $info = $this->roomModel->getRoomTop($roomId);
            if(empty($info)) {
                $code = Hint::PARAM_ERROR;
                $msg = '数据不存在';
                break;
            }
            $upData = [
                'sort_num' => $sortNum,
                'time_st' => $timeSt,
                'time_ed' => $timeEd,
            ];
            $id = $this->roomModel->updateRoomTop($info['id'], $upData);

        } while (false);
        return compact('code', 'msg', 'data');
    }

    /**
     * 删除置顶房间
     */
    public function topRoomDel($roomId)
    {
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        do {
            if(empty($roomId)) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            //是否存在
            $info = $this->roomModel->getRoomTop($roomId);
            if(empty($info)) {
                $code = Hint::PARAM_ERROR;
                $msg = '数据不存在';
                break;
            }
            $upData = [
                'is_delete' => 1
            ];
            $id = $this->roomModel->updateRoomTop($info['id'], $upData, ['is_delete'=>0]);

        } while (false);
        return compact('code', 'msg', 'data');
    }

    /**
     * 获取开启的房间
     */
    public function getOpenRoomIds($roomIds)
    {
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        do {
            if(empty($roomIds)) {
                break;
            }
            $roomIds = array_values(array_filter(explode(',', $roomIds)));
            if(empty($roomIds)) {
                break;
            }
            $list = [];
            foreach($roomIds as $roomId) {
                $roomOpenId = $this->roomModel->getRoomOpenList($roomId, 'roomOpenId');
                $list[$roomId] = empty($roomOpenId) ? 0 : 1;
            }
            $data['list'] = $list;

        } while (false);
        return compact('code', 'msg', 'data');
    }

    /**
     * 获取已开启的房间列表
     */
    public function getOpenRoomList($userId, $type, $page)
    {
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        do {


        } while (false);
        return compact('code', 'msg', 'data');
    }

    /**
     * 获取房间总麦是否关闭
     * @param $room_id
     * @return int
     */
    public function get_volume_closed($room_id)
    {
        return $this->roomModel->get_volume_closed($room_id);
    }

    /**
     * 房间解除用户踢出
     */
    public function revokeShotoff($roomId, $roomUserId, $toUserId)
    {
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];

        do {
            $role = $this->roomModel->get_role($roomId, $roomUserId);
            if ($role == 0) {
                $code = Hint::AUTH_ERROR;
                break;
            }
            //查看是否踢出状态
            $ifShotoff = $this->roomModel->get_shotoff($roomId, $toUserId);
            if($ifShotoff) {
                $this->roomModel->del_shotoff($roomId, $toUserId);
            }

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 设置房间分成用户
     */
    public function setRoomFinanceUser($userId, $roomId, $adminId=0){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        do {
            if(empty($roomId) || empty($adminId)) {
                $code = Hint::PARAM_ERROR;
                break;
            }

            DB::beginTransaction();
            try {
                //删除
                $this->roomModel->deleteRoomFinanceUserTable($roomId);

                //新增
                $id = $this->roomModel->addRoomFinanceUserTable($userId, $roomId, $adminId);

                DB::commit();
            } catch (\Exception $e) {
                DB::rollBack();
                $code = Hint::ERROR;
                echo $e->getMessage();
                break;
            }

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 添加房间欢迎语
     */
    public function addRoomWelcomeWord($loginUserId, $roomId, $content)
    {
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];

        do {
            //权限
            $role = $this->roomModel->get_role($roomId, $loginUserId);
            if ($role == 0) {
                $code = Hint::AUTH_ERROR;
                break;
            }
            //获取公会
            $unionInfo = $this->model_union->getUnionByRoomId($roomId);
            if(empty($unionInfo)) {
                $code = Hint::NOT_ALLOWED;
                $msg = '房间不是归属于认证公会';
                break;
            }
            if($unionInfo['stop'] != 1) {
                $code = Hint::NOT_ALLOWED;
                $msg = '房间不是归属于认证公会';
                break;
            }
            if($unionInfo['authentication_status'] < 1) {
                $code = Hint::NOT_ALLOWED;
                $msg = '房间不是归属于认证公会';
                break;
            }
            $hasNum = $this->roomModel->getRoomWelcomeWordNum($roomId);
            if($hasNum >= 20) {
                $code = Hint::NOT_ALLOWED;
                $msg = '欢迎语配置条数最多20条';
                break;
            }

            //新增
            $id = $this->roomModel->addRoomWelcomeWord(['union_id'=>$unionInfo['id'], 'room_id'=>$roomId, 'content'=>$content]);

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 编辑房间欢迎语
     */
    public function editRoomWelcomeWord($loginUserId, $id, $content)
    {
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];

        do {
            //获取
            $info = $this->roomModel->getRoomWelcomeWordById($id);
            if(empty($info)) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            $roomId = $info['room_id'];

            //权限
            $role = $this->roomModel->get_role($roomId, $loginUserId);
            if ($role == 0) {
                $code = Hint::AUTH_ERROR;
                break;
            }

            //更新
            $id = $this->roomModel->editRoomWelcomeWord([$id], $roomId, ['audit_status'=>1, 'content'=>$content]);

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 删除房间欢迎语
     */
    public function delRoomWelcomeWord($loginUserId, $ids)
    {
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];

        do {
            $roomId = 0;
            $flag = 0;
            foreach($ids as $id) {
                //获取
                $info = $this->roomModel->getRoomWelcomeWordById($id);
                if(empty($info)) {
                    $flag = 1;
                    continue;
                }else{
                    if($roomId == 0) {
                        $roomId = $info['room_id'];
                    }else{
                        if($roomId != $info['room_id']) {
                            $flag = 1;
                            continue;
                        }
                    }
                }
            }
            if(empty($roomId) || $flag==1) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            //权限
            $role = $this->roomModel->get_role($roomId, $loginUserId);
            if ($role == 0) {
                $code = Hint::AUTH_ERROR;
                break;
            }

            //更新
            $id = $this->roomModel->editRoomWelcomeWord($ids, $roomId, ['is_delete'=>1]);

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 房间欢迎语列表
     */
    public function listRoomWelcomeWord($loginUserId, $roomId)
    {
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];

        do {
            //权限
            $role = $this->roomModel->get_role($roomId, $loginUserId);
            if ($role == 0) {
                $code = Hint::AUTH_ERROR;
                break;
            }

            $list = $this->roomModel->getRoomWelcomeWordAll($roomId);
            $data['list'] = $list;

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 获取房间欢迎语随机一条
     */
    public function randRoomWelcomeWord($loginUserId, $roomId)
    {
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];

        do {
            $data['content'] = '';
            $list = $this->roomModel->getRoomWelcomeWord($roomId);
            if(!empty($list)) {
                $data['content'] = $list[array_rand($list)]['content'];
            }
            if(empty($data['content'])) {
                $code = Hint::PARAM_ERROR;
                $msg = '请先设置欢迎语';
                break;
            }

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 获取房主为自己的CBD房间列表
     */
    public function selfRoomList($userId){
        do{
            $code = Hint::SUCCESS;
            $msg = 'ok';
            $data = [];
            $union_info = $this->model_union_user->userToUnion($userId, 1);
            if(empty($union_info)){
                break;
            }
            $union_id = $union_info['un_id'];
            //查看公会房间id
            $union_rooms = $this->model_union->getUnionRoomIds($union_id);
            if(!empty($union_rooms)){
                foreach($union_rooms as $k=>$room){
                    $union_rooms[$k]['image'] = build_image($room['image']);
                }
                $data = $union_rooms;
            }
        }while(false);
        return compact('code','msg','data');
    }

    /**
     * 获取房间每小时结算流水
     */
    public function hourRoomBill($userId, $roomId, $date){
        do{
            $code = Hint::SUCCESS;
            $msg = 'ok';
            $data = [];
            //权限检查
            $role = $this->roomModel->get_role($roomId, $userId);
            if ($role != 2) {
                $code = Hint::AUTH_ERROR;
                $msg = '无权限';
                break;
            }
            //获取用户当前所在的房间所属公会
            $unionInfo = $this->model_union->getUnionByRoomId($roomId);
            //获取公会下所有房间id
            $allUnionRooms = $this->model_union->getUnionRoomIds($unionInfo['id']);
            if(empty($allUnionRooms)){
                $code = Hint::ERR_NORMAL;
                $msg = '非公会房间';
                break;
            }
            $allUnionRooms = array_column($allUnionRooms,'room_id');
            if(!in_array($roomId, $allUnionRooms)){
                $code = Hint::AUTH_ERROR;
                $msg = '无权限';
                break;
            }
            $date = empty($date) ? date('Y-m-d',time()) : $date;
            //查询流水
            $data = $this->model_union->getHourRoomBill($roomId, $date);
            $searchRoomInfo = $this->roomModel->get_room($roomId);
            foreach($data as $k=>$v){
                $data[$k]['room_uid'] = $searchRoomInfo['room_uid'];
                $data[$k]['name'] = $searchRoomInfo['name'];
            }
        }while(false);
        return compact('code','msg','data');
    }

    /**
     * 审核房间欢迎语
     */
    public function auditRoomWelcomeWord($id, $auditStatus)
    {
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];

        do {
            //获取
            $info = $this->roomModel->getRoomWelcomeWordById($id);
            if(empty($info)) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            $roomId = $info['room_id'];

            //更新
            $id = $this->roomModel->editRoomWelcomeWord([$id], $roomId, ['audit_status'=>$auditStatus]);

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 房间锁麦
     */
    public function roomLockMicro($roomId, $userId, $microId)
    {
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        $now = time();

        do {
            //权限
            $role = $this->roomModel->get_role($roomId, $userId);
            if ($role == 0) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            //麦位用户
            $miroUserId = $this->roomMicroModel->get_user_id($roomId, $microId);
            if(empty($miroUserId)) {
                $code = Hint::PARAM_ERROR;
                $msg = '当前麦位没有用户';
                break;
            }
            //房间信息
            $roomInfo = $this->roomModel->get_room($roomId);
            if(empty($roomInfo)) {
                $code = Hint::PARAM_ERROR;
                $msg = '房间信息获取失败';
                break;
            }
            if($roomInfo['room_type']["id"] == 46) {
                $code = Hint::PARAM_ERROR;
                $msg = '拍拍房不可锁麦';
                break;
            }


            //锁麦设置
            $log = [
                'room_id' => $roomId,
                'micro_id' => $microId,
                'lock_user_id' => $miroUserId,//麦上用户ID
                'room_user_id' => $userId,//房间管理用户ID
                'status' => 1,
                'now' => $now,
            ];
            $this->roomMicroModel->setRoomLockMicro($roomId, $microId, $log);

            //通知
            $this->roomMsgService->roomMicroLockMsg($roomId, $log, 1);
            $this->msgService->userMicroLockMsg($log['lock_user_id'], $log, 1);

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 房间解除锁麦
     */
    public function roomUnLockMicro($roomId, $userId, $microId)
    {
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        $now = time();

        do {
            //权限
            $role = $this->roomModel->get_role($roomId, $userId);
            if ($role == 0) {
                $code = Hint::AUTH_ERROR;
                break;
            }
            //是否锁麦
            $info = $this->roomMicroModel->getRoomLockMicro($roomId, $microId);
            if(empty($info)) {
                $code = Hint::PARAM_ERROR;
                $msg = '当前麦位没有锁麦';
                break;
            }
            if($info['room_user_id'] != $userId) {
                //房间信息
                $roomInfo = $this->roomModel->get_room($roomId);
                if(empty($roomInfo) || $roomInfo['user_id']!=$userId) {
                    $code = Hint::PARAM_ERROR;
                    $msg = '锁麦只能由操作的用户解锁';
                    break;
                }
            }
            //删除
            $this->roomMicroModel->delRoomLockMicro($roomId, $microId);

            //通知
            $this->roomMsgService->roomMicroLockMsg($roomId, $info, 0);
            $this->msgService->userMicroLockMsg($info['lock_user_id'], $info, 0);

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 下麦确认
     */
    public function outMicroConfirm($roomId, $userId)
    {
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        $now = time();

        do {
            //主持麦用户ID
            $roomMicroHostUserId = $this->roomHostMicroModel->get_user_id($roomId);
            if($userId == $roomMicroHostUserId) {
                //主持麦下麦数据处理
                $result = $this->newRoomMicroService->userHostMicroOutForData($roomId, $userId);
                if($result['code']==Hint::SUCCESS || $result['code']!=Hint::ROOM_MICRO_NOT_EXIST) {
                    break;
                }
            }else{
                //校验
                $checkRes = $this->newRoomMicroService->checkRoomUserCanQuit($roomId, $userId);
                if($checkRes['code'] != Hint::SUCCESS) {
                    if($checkRes['code'] == Hint::ROOM_MICRO_USER_LOCK) {
                        $code = Hint::ROOM_MICRO_USER_LOCK;
                        $msg = '已被锁麦，请先解锁';
                        break;
                    }
                    if($checkRes['code'] == Hint::ROOM_PAIPAI_LOCK) {
                        $code = Hint::ROOM_PAIPAI_LOCK;
                        $msg = '已产生心动值不可下麦 来自确认下麦接口';
                        break;
                    }
                }

                //普通麦下麦数据处理
                $result = $this->newRoomMicroService->userMicroOutForData($roomId, $userId);
                if($result['code']==Hint::SUCCESS || $result['code']!=Hint::ROOM_MICRO_NOT_EXIST) {
                    break;
                }
            }
        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 普通麦抱下麦
     */
    public function roomMicroOut($roomId, $userId)
    {
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        $now = time();

        do {
            //校验
            $checkRes = $this->newRoomMicroService->checkRoomUserCanQuit($roomId, $userId);
            if($checkRes['code'] != Hint::SUCCESS) {
                if($checkRes['code'] == Hint::ROOM_MICRO_USER_LOCK) {
                    $code = Hint::ROOM_MICRO_USER_LOCK;
                    $msg = '已被锁麦，请先解锁';
                    break;
                }
                if($checkRes['code'] == Hint::ROOM_PAIPAI_LOCK) {
                    $code = Hint::ROOM_PAIPAI_LOCK;
                    break;
                }
            }

            if (!redis_lock($this->micro_lock_key.$roomId, 5)){
                $code = Hint::NOT_ALLOWED;
                break;
            }

            $microId = $checkRes['data']['micro_id'];
            if($microId > -1) {
                $this->roomMsgService->command_micro_out($roomId, $microId, $userId);
            }

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 普通麦抱下麦
     */
    public function roomMicroBeOut($roomId, $microId, $roomUserId)
    {
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        $now = time();

        do {
            $role = $this->roomModel->get_role($roomId, $roomUserId);
            if ($role == 0) {
                $code = Hint::AUTH_ERROR;
                break;
            }
            $micro = $this->roomMicroModel->get_micro($roomId, $microId);
            if(empty($micro['user_id'])) {
                break;
            }
            $userId = $micro['user_id'];

            //校验
            $checkRes = $this->newRoomMicroService->checkRoomUserCanQuit($roomId, $userId);
            if($checkRes['code'] != Hint::SUCCESS) {
                if($checkRes['code'] == Hint::ROOM_MICRO_USER_LOCK) {
                    $code = Hint::ROOM_MICRO_USER_LOCK;
                    $msg = '已被锁麦，请先解锁';
                    break;
                }
                if($checkRes['code'] == Hint::ROOM_PAIPAI_LOCK) {
                    $code = Hint::ROOM_PAIPAI_LOCK;
                    break;
                }
            }

            //普通麦下麦数据处理
            $this->newRoomMicroService->userMicroOutForData($roomId, $userId);
        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 主持麦抱下麦
     */
    public function roomHostMicroBeOut($roomId, $roomUserId)
    {
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        $now = time();

        do {
            $role = $this->roomModel->get_role($roomId, $roomUserId);
            if ($role != 2) {
                $code = Hint::AUTH_ERROR;
                break;
            }
            //主持麦用户
            $roomMicroHostUserId = (int) $this->roomHostMicroModel->get_user_id($roomId);
            if(empty($roomMicroHostUserId)) {
                $code = Hint::ROOM_MICRO_IS_NULL;
                break;
            }
            if (!redis_lock($this->micro_lock_key . $roomId, 5)){
                $code = Hint::NOT_ALLOWED;
                break;
            }

            //普通麦下麦数据处理
            $this->newRoomMicroService->userHostMicroOutForData($roomId, $roomMicroHostUserId);
        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 上麦确认
     */
    public function intoMicroConfirm($roomId, $userId)
    {
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        $now = time();

        do {
            //主持麦上麦数据处理
            $result = $this->newRoomMicroService->userHostMicroIntoForData($roomId, $userId);
            if($result['code']==Hint::SUCCESS || $result['code']!=Hint::ROOM_MICRO_NOT_EXIST) {
                break;
            }
            //普通麦上麦数据处理
            $result = $this->newRoomMicroService->userMicroIntoForData($roomId, $userId);
            if($result['code']==Hint::SUCCESS || $result['code']!=Hint::ROOM_MICRO_NOT_EXIST) {
                break;
            }
            return $result;
        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 离开房间
     */
    public function roomUserQuit($roomId, $userId)
    {
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        $now = time();

        do {
            //用户离开房间数据处理
            $result = $this->newRoomMicroService->roomUserQuitForData($roomId, $userId);
            if($result['code']==Hint::SUCCESS || in_array($result['code'], [Hint::ROOM_MICRO_USER_LOCK, Hint::ROOM_PAIPAI_LOCK])) {
                break;
            }

            return $result;
        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 拍拍房处理麦位变化通知处理
     */
    public function handleRoomPaiPai($body)
    {
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        $now = time();

        do {
            try {
                //普通麦 0嘉宾位 1:2 3:4 5:6
                if(empty($body['room_id'])) {
                    break;
                }
                $roomId = $body['room_id'];
                $roomInfo = $this->roomModel->get_room($roomId);

                //没开始
                $cacheKey = $this->roomPaiPaiKey.$roomId;
                $info = Redis::HGETALL($cacheKey);
                if(empty($info)) {
                    break;
                }
                //已结束
                if($info['status']!=1 || (strtotime($info['created_at'])+$info['second_num'])<$now) {
                    break;
                }

                //主持麦用户
                $roomMicroHostUserId = (int) $this->roomHostMicroModel->get_user_id($roomId);
                //普通麦用户
                $roomMicroMap[0] = (int) $this->roomMicroModel->get_user_id($roomId, 0);
                $roomMicroMap[1] = (int) $this->roomMicroModel->get_user_id($roomId, 1);
                $roomMicroMap[2] = (int) $this->roomMicroModel->get_user_id($roomId, 2);
                $roomMicroMap[3] = (int) $this->roomMicroModel->get_user_id($roomId, 3);
                $roomMicroMap[4] = (int) $this->roomMicroModel->get_user_id($roomId, 4);
                $roomMicroMap[5] = (int) $this->roomMicroModel->get_user_id($roomId, 5);
                $roomMicroMap[6] = (int) $this->roomMicroModel->get_user_id($roomId, 6);
                $oldMicroUserIds = [];//旧的麦位和用户关系 用户=>麦位
                foreach($roomMicroMap as $k1=>$v1) {
                    if(!empty($v1)) {
                        $oldMicroUserIds[$v1] = [
                            'micro_id' => $k1,
                            'volume' => (int) $this->roomMicroModel->get_volume($roomId, $k1),
                            'volume_self' => (int) $this->roomMicroModel->get_volume_self($roomId, $k1),
                        ];
                    }
                }

                //收了礼物的
                $cacheKey1 = $this->roomPaiPaiGetGiftUserKey.$info['logId'];
                $userIds = Redis::SMEMBERS($cacheKey1);
                //拍拍房收礼送礼用户排行
                $rankList = [];
                $cacheKey2 = $this->roomPaiPaiUserRankKey.$info['logId'];
                $allSort = Redis::zrevrange($cacheKey2, 0, 500,['withscores'=>true]);
                foreach($allSort as $k1=>$v1) {
                    $k1 = explode('|', $k1);
                    $userId1 = $k1[0];
                    $userId2 = $k1[1];
                    //主持麦不要
                    if($userId1==$roomMicroHostUserId || $userId2==$roomMicroHostUserId) {
                        continue;
                    }

                    $item = [
                        'to_user_id' => $userId1,
                        'from_user_id' => $userId2,
                        'score' => $v1,
                    ];
                    $rankList[] = $item;
                }
                array_multisort(array_column($rankList, 'score'), SORT_DESC, $rankList);

                //新麦位计算
                $roomMicroMapNew = [];
                $nowMicroUserList = [];
                $scoreMap = ['score_34' => 0, 'score_12' => 0, 'score_56' => 0,];//麦位积分
                for($i=0;$i<count($rankList);$i++) {
                    if(empty($rankList[$i])) {
                        break;
                    }
                    $item = $rankList[$i];
                    //第一名
                    if($i == 0) {
                        if($roomMicroMap[3] == $item['to_user_id']) {
                            $roomMicroMapNew[3] = $item['to_user_id'];
                            $roomMicroMapNew[4] = $item['from_user_id'];
                        }elseif($roomMicroMap[4]==$item['to_user_id']) {
                            $roomMicroMapNew[3] = $item['from_user_id'];
                            $roomMicroMapNew[4] = $item['to_user_id'];
                        }elseif($roomMicroMap[3] == $item['from_user_id']) {
                            $roomMicroMapNew[3] = $item['from_user_id'];
                            $roomMicroMapNew[4] = $item['to_user_id'];
                        }elseif($roomMicroMap[4] == $item['from_user_id']) {
                            $roomMicroMapNew[3] = $item['to_user_id'];
                            $roomMicroMapNew[4] = $item['from_user_id'];
                        }else{
                            $roomMicroMapNew[3] = $item['to_user_id'];
                            $roomMicroMapNew[4] = $item['from_user_id'];
                        }
                        $nowMicroUserList[] = $item['to_user_id'];
                        $nowMicroUserList[] = $item['from_user_id'];
                        $scoreMap['score_34'] = $item['score'];
                        continue;
                    }
                    if(in_array($item['to_user_id'], $nowMicroUserList) || in_array($item['from_user_id'], $nowMicroUserList)) {
                        continue;
                    }
                    //第二名
                    if(empty($roomMicroMapNew[1])) {
                        if($roomMicroMap[1] == $item['to_user_id']) {
                            $roomMicroMapNew[1] = $item['to_user_id'];
                            $roomMicroMapNew[2] = $item['from_user_id'];
                        }elseif($roomMicroMap[2]==$item['to_user_id']) {
                            $roomMicroMapNew[1] = $item['from_user_id'];
                            $roomMicroMapNew[2] = $item['to_user_id'];
                        }elseif($roomMicroMap[1] == $item['from_user_id']) {
                            $roomMicroMapNew[1] = $item['from_user_id'];
                            $roomMicroMapNew[2] = $item['to_user_id'];
                        }elseif($roomMicroMap[2] == $item['from_user_id']) {
                            $roomMicroMapNew[1] = $item['to_user_id'];
                            $roomMicroMapNew[2] = $item['from_user_id'];
                        }else{
                            $roomMicroMapNew[1] = $item['to_user_id'];
                            $roomMicroMapNew[2] = $item['from_user_id'];
                        }
                        $nowMicroUserList[] = $item['to_user_id'];
                        $nowMicroUserList[] = $item['from_user_id'];
                        $scoreMap['score_12'] = $item['score'];
                        continue;
                    }
                    //第三名
                    if(empty($roomMicroMapNew[5])) {
                        if($roomMicroMap[5] == $item['to_user_id']) {
                            $roomMicroMapNew[5] = $item['to_user_id'];
                            $roomMicroMapNew[6] = $item['from_user_id'];
                        }elseif($roomMicroMap[6]==$item['to_user_id']) {
                            $roomMicroMapNew[5] = $item['from_user_id'];
                            $roomMicroMapNew[6] = $item['to_user_id'];
                        }elseif($roomMicroMap[5] == $item['from_user_id']) {
                            $roomMicroMapNew[5] = $item['from_user_id'];
                            $roomMicroMapNew[6] = $item['to_user_id'];
                        }elseif($roomMicroMap[6] == $item['from_user_id']) {
                            $roomMicroMapNew[5] = $item['to_user_id'];
                            $roomMicroMapNew[6] = $item['from_user_id'];
                        }else{
                            $roomMicroMapNew[5] = $item['to_user_id'];
                            $roomMicroMapNew[6] = $item['from_user_id'];
                        }
                        $nowMicroUserList[] = $item['to_user_id'];
                        $nowMicroUserList[] = $item['from_user_id'];
                        $scoreMap['score_56'] = $item['score'];
                        break;
                    }
                }

                //根据相同位置的旧麦位填补数据
                $microIds = [1, 2, 3, 4, 5, 6];
                foreach($microIds as $i) {
                    if(empty($roomMicroMapNew[$i]) && !empty($roomMicroMap[$i]) && !in_array($roomMicroMap[$i], $nowMicroUserList)) {
                        $roomMicroMapNew[$i] = $roomMicroMap[$i];
                        $nowMicroUserList[] = $roomMicroMap[$i];
                    }
                }
                //旧麦用户看看有没有空位
                foreach($microIds as $i) {
                    if(!empty($roomMicroMap[$i]) && !in_array($roomMicroMap[$i], $nowMicroUserList)) {
                        if(in_array($i, [1, 3, 5])) {
                            $microIdsV2 = [1, 3, 5, 2, 4, 6];
                        }elseif(in_array($i, [2, 4, 6])) {
                            $microIdsV2 = [2, 4, 6, 1, 3, 5];
                        }
                        foreach($microIdsV2 as $i2) {
                            if(empty($roomMicroMapNew[$i2])) {
                                $roomMicroMapNew[$i2] = $roomMicroMap[$i];
                                $nowMicroUserList[] = $roomMicroMap[$i];
                                break;
                            }
                        }
                    }
                }

                //如果嘉宾位用户去了普通麦位那么嘉宾位没有用户
                if(in_array($roomMicroMap[0], $nowMicroUserList)) {
                    $roomMicroMapNew[0] = 0;
                }else{
                    $roomMicroMapNew[0] = $roomMicroMap[0];
                }

                //麦位用户变了
                for($i=0;$i<7;$i++) {
                    //这个麦位没有用户
                    if(empty($roomMicroMap[$i])) {
                        continue;
                    }
                    //这个麦位没有变化用户                
                    if($roomMicroMapNew[$i] == $roomMicroMap[$i]) {
                        continue;
                    }
                    //下麦
                    $res1 = $this->newRoomMicroService->userMicroOutForData($roomId, $roomMicroMap[$i], $i, 0, 0, 0);
                }
                //获取全麦是否关闭
                $roomVolumeClosed = $this->roomModel->get_volume_closed($roomId);

                for($i=0;$i<7;$i++) {
                    //这个麦位没有用户
                    if(empty($roomMicroMapNew[$i])) {
                        $this->roomMicroModel->volume_self_open($roomId, $i);
                        //是否全员闭麦
                        if($roomVolumeClosed == 1) {
                            $this->roomMicroModel->volume_close($roomId, $i);
                        }else{
                            $this->roomMicroModel->volume_open($roomId, $i);
                        }
                        continue;
                    }
                    //这个麦位没有变化用户
                    if($roomMicroMapNew[$i] == $roomMicroMap[$i]) {
                        continue;
                    }
                    //上麦
                    $res2 = $this->newRoomMicroService->userMicroIntoForData($roomId, $roomMicroMapNew[$i], $i, 0);
                    //用户的旧麦位ID
                    $oldMicroInfo = isset($oldMicroUserIds[$roomMicroMapNew[$i]]) ? $oldMicroUserIds[$roomMicroMapNew[$i]] : [];
                    if(!empty($oldMicroInfo)) {
                        if($oldMicroInfo['volume'] == 1) {
                            $this->roomMicroModel->volume_open($roomId, $i);
                        }else{
                            $this->roomMicroModel->volume_close($roomId, $i);
                        }
                        if($oldMicroInfo['volume_self'] == 1) {
                            $this->roomMicroModel->volume_self_open($roomId, $i);
                        }else{
                            $this->roomMicroModel->volume_self_close($roomId, $i);
                        }
                    }
                }

                //麦位积分记录
                Redis::HSET($cacheKey, 'score_12', $scoreMap['score_12']);
                Redis::HSET($cacheKey, 'score_34', $scoreMap['score_34']);
                Redis::HSET($cacheKey, 'score_56', $scoreMap['score_56']);
                Redis::HSET($cacheKey, 'micro_list', json_encode($roomMicroMapNew));

                //麦列表
                $micros = $this->roomMicroModel->get_micros($roomId, $roomInfo['room_type']['id']); //room type从房间获得。
                for ($i = 0; $i < count($micros); $i++){
                    if($micros[$i]["user_id"] !== null){
                        $micros[$i]["user"] = $this->userModel->get_user($micros[$i]["user_id"]);
                        $micros[$i]["user"]['attires'] = $this->mallModel->getGoodsAttire($micros[$i]["user_id"]);
                    }else{
                        $micros[$i]["user"] = null;
                    }
                    unset($micros[$i]["user_id"]);
                }

                //整理数据
                $data['info'] = Redis::HGETALL($cacheKey);
                $data['info']['end_time'] = strtotime($data['info']['created_at']) + $data['info']['second_num'];
                $data['roomMicroMap'] = $roomMicroMapNew;
                //历史数据
                $cacheKey3 = $this->roomPaiPaiMicroKey.$info['logId'];
                $str = Redis::GET($cacheKey3);
                // write_log('paipai', '送礼脚本', ['room_id'=>$roomId, 'roomMicroMap'=>$roomMicroMap, 'roomMicroMapNew'=>$roomMicroMapNew, 'str'=>$str, 'str2'=>json_encode($data)]);
                if($str !== json_encode($data)) {
                    // write_log('paipai', '拍拍房麦位变化消息', ['room_id'=>$roomId, 'info'=>$data['info'], 'micros'=>$micros]);
                    //拍拍房麦位变化消息
                    $this->roomMsgService->roomPaiPaiMicroMsg($roomId, $data['info'], $micros);
                }
                Redis::SET($cacheKey3, json_encode($data));
                Redis::EXPIRE($cacheKey, 86400);
            } catch (\Exception $e) {
                write_log('error_paipai', '拍拍房处理麦位变化通知处理', ['room_id'=>$roomId, 'msg'=>$e->getMessage(), 'line'=>$e->getLine()]);
            }

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 拍拍房开始牵线
     */
    public function roomPaiPaiOpen($roomId, $userId)
    {
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        $now = time();
        $limit = 600;

        do {
            //主持麦用户ID
            $roomMicroHostUserId = $this->roomHostMicroModel->get_user_id($roomId);
            if(empty($roomMicroHostUserId) || $roomMicroHostUserId!=$userId) {
                $code = Hint::AUTH_ERROR;
                break;
            }
            //是否进行中
            $cacheKey = $this->roomPaiPaiKey.$roomId;
            $info = Redis::HGETALL($cacheKey);
            if(!empty($info)) {
                $code = Hint::PARAM_ERROR;
                $msg = '进行中 请停止后开启新的';
                break;
            }

            //记录
            $log = [
                'room_id' => $roomId,
                'open_user_id' => $userId,
                'second_num' => $limit,
                'end_time' => '0000:00:00 00:00',
                'created_at' => date('Y-m-d H:i:s', $now),
            ];

            $logId = $this->roomModel->addRoomPaipaiLog($log);
            if(empty($logId)) {
                $code = Hint::ERROR;
                break;
            }
            $log['status'] = 1;
            $log['score_12'] = 0;
            $log['score_34'] = 0;
            $log['score_56'] = 0;
            $log['logId'] = $logId;
            Redis::HMSET($cacheKey, $log);
            Redis::EXPIRE($cacheKey, 86400);

            //拍拍房通用消息
            $this->roomMsgService->roomPaiPaiAddTimeMsg($roomId, ($now+$limit), $log['status']);

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 拍拍房加时
     */
    public function roomPaiPaiAddTime($roomId, $userId)
    {
        $code = Hint::SUCCESS;
        $msg = '心动表白加时10分钟';
        $data = [];
        $now = time();
        $limit = 600;

        do {
            //主持麦用户ID
            $roomMicroHostUserId = $this->roomHostMicroModel->get_user_id($roomId);
            if(empty($roomMicroHostUserId) || $roomMicroHostUserId!=$userId) {
                $code = Hint::AUTH_ERROR;
                break;
            }
            //是否进行中
            $cacheKey = $this->roomPaiPaiKey.$roomId;
            $info = Redis::HGETALL($cacheKey);
            if(empty($info)) {
                $code = Hint::PARAM_ERROR;
                $msg = '未开始';
                break;
            }
            $endTime = strtotime($info['created_at'])+$info['second_num'];
            if($info['status']!=1 || $endTime<$now) {
                $code = Hint::PARAM_ERROR;
                $msg = '结束时间已到';
                break;
            }
            if($info['second_num'] >= 3600) {
                $code = Hint::PARAM_ERROR;
                $msg = '心动表白最多加时5次';
                break;
            }
            $this->roomModel->editRoomPaipaiLog($info['logId'], ['incr_second_num'=>$limit]);

            Redis::HINCRBY($cacheKey, 'second_num', $limit);

            //拍拍房通用消息
            $this->roomMsgService->roomPaiPaiAddTimeMsg($roomId, ($endTime + $limit), $info['status']);

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 拍拍房查询结果
     */
    public function roomPaiPaiGetResult($roomId, $userId)
    {


        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        $now = time();

        do {
            $data['score'] = 0;
            $data['user_left'] = (object) [];
            $data['user_right'] = (object) [];
            $data['list'] = [];
            //是否进行中
            $cacheKey = $this->roomPaiPaiKey.$roomId;
            $info = Redis::HGETALL($cacheKey);
            if(empty($info)) {
                $code = Hint::PARAM_ERROR;
                $msg = '未开始';
                break;
            }
            $list = [];
            if($info['score_34'] > 0) {
                $data['score'] = $info['score_34'];
                $rankList = $this->relationModel->getRelationRank();
                foreach($rankList as $val) {
                    //十五天
                    if($val['day_15']>0 && $info['score_34']>=$val['day_15']) {
                        $list[] = [
                            'rank_id' => $val['rank_id'],
                            'rank_name' => $val['rank_name'].' 15 天',
                            'rank_name_base' => $val['rank_name'],
                            'image' => $val['image'],
                            'colour' => $val['colour'],
                            'day' => 15,
                        ];
                        continue;
                    }
                    //七天
                    if($val['day_7']>0 && $info['score_34']>=$val['day_7']) {
                        $list[] = [
                            'rank_id' => $val['rank_id'],
                            'rank_name' => $val['rank_name'].' 7 天',
                            'rank_name_base' => $val['rank_name'],
                            'image' => $val['image'],
                            'colour' => $val['colour'],
                            'day' => 7,
                        ];
                        continue;
                    }
                    //三天
                    if($val['day_3']>0 && $info['score_34']>=$val['day_3']) {
                        $list[] = [
                            'rank_id' => $val['rank_id'],
                            'rank_name' => $val['rank_name'].' 3 天',
                            'rank_name_base' => $val['rank_name'],
                            'image' => $val['image'],
                            'colour' => $val['colour'],
                            'day' => 3,
                        ];
                        continue;
                    }
                }
                $data['list'] = $list;

                $microList = json_decode($info['micro_list'], true);
                if(!empty($microList['3'])) {
                    $userLeft = $this->userModel->get_user($microList['3']);
                    $data['user_left'] = [
                        'user_id' => $userLeft['user_id'],
                        'user_uid' => $userLeft['user_uid'],
                        'nickname' => $userLeft['nickname'],
                        'gender' => $userLeft['gender'],
                        'images' => $userLeft['images'],
                    ];
                }

                if(!empty($microList['4'])) {
                    $userRight = $this->userModel->get_user($microList['4']);
                    $data['user_right'] = [
                        'user_id' => $userRight['user_id'],
                        'user_uid' => $userRight['user_uid'],
                        'nickname' => $userRight['nickname'],
                        'gender' => $userRight['gender'],
                        'images' => $userRight['images'],
                    ];
                }
            }

            if(empty($data['score'])) {
                $code = Hint::PARAM_ERROR;
                $msg = '当前无可拍的关系';
            }

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 拍拍房确定结果
     */
    public function roomPaiPaiDefine($roomId, $userId)
    {
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        $now = time();

        do {
            //主持麦用户ID
            $roomMicroHostUserId = $this->roomHostMicroModel->get_user_id($roomId);
            if(empty($roomMicroHostUserId) || $roomMicroHostUserId!=$userId) {
                $code = Hint::AUTH_ERROR;
                break;
            }
            //是否进行中
            $cacheKey = $this->roomPaiPaiKey.$roomId;
            $info = Redis::HGETALL($cacheKey);
            if(empty($info)) {
                $code = Hint::PARAM_ERROR;
                $msg = '未开始';
                break;
            }
            if($info['status'] != 1) {
                if($info['status'] == 2) {
                    $result = $this->roomPaiPaiGetResult($roomId, $userId);
                    $data = $result['data'];
                    break;
                }
                $code = Hint::PARAM_ERROR;
                $msg = '不是进行中的';
                break;
            }
            $endTime = strtotime($info['created_at'])+$info['second_num'];

            Redis::HSET($cacheKey, 'status', 2);
            Redis::HSET($cacheKey, 'end_time', date('Y-m-d H:i:s', $now));

            $this->roomModel->editRoomPaipaiLog($info['logId'], ['end_time'=>date('Y-m-d H:i:s', $now)]);

            $result = $this->roomPaiPaiGetResult($roomId, $userId);
            $data = $result['data'];

            //拍拍房通用消息
            $this->roomMsgService->roomPaiPaiAddTimeMsg($roomId, $endTime, 2, $data);

            //没有可发的直接结束
            if(empty($data['list'])) {
                $this->roomPaiPaiEnd($roomId, $userId, 0, 0);
            }

            if(empty($data['score'])) {
                $code = Hint::PARAM_ERROR;
                $msg = '当前无可拍的关系';
            }

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 拍拍房结束并派发
     */
    public function roomPaiPaiEnd($roomId, $userId, $rankId, $day)
    {
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        $now = time();

        do {
            //主持麦用户ID
            $roomMicroHostUserId = $this->roomHostMicroModel->get_user_id($roomId);
            if(empty($roomMicroHostUserId) || $roomMicroHostUserId!=$userId) {
                $code = Hint::AUTH_ERROR;
                break;
            }
            //是否进行中
            $cacheKey = $this->roomPaiPaiKey.$roomId;
            $info = Redis::HGETALL($cacheKey);
            if(empty($info)) {
                $code = Hint::PARAM_ERROR;
                $msg = '未开始';
                break;
            }
            if($info['status'] != 2) {
                $code = Hint::PARAM_ERROR;
                $msg = '结果未确定';
                break;
            }

            Redis::HSET($cacheKey, 'status', 3);

            //获取结果
            $result = $this->roomPaiPaiGetResult($roomId, $userId);
            $list = $result['data']['list'];
            $rankInfo = [];
            foreach($list as $val) {
                if($val['rank_id']==$rankId && $val['day']==$day) {
                    $val['rank_name'] = $val['rank_name_base'];
                    $rankInfo = $val;
                    break;
                }
            }
            if(!empty($rankInfo)) {
                $result['data']['result'] = $rankInfo;
                //记录
                $log = [
                    'user_id_1' => min($result['data']['user_left']['user_id'], $result['data']['user_right']['user_id']),
                    'user_id_2' => max($result['data']['user_left']['user_id'], $result['data']['user_right']['user_id']),
                    'rank_id' => $rankInfo['rank_id'],
                    'day' => $rankInfo['day'],
                    'room_id' => $roomId,
                    'log_id' => $info['logId'],
                ];
                $this->relationModel->addUserRelationLog($log);

                //系统消息
//                $this->msgService->sendUserWithUrlMsg($result['data']['user_left']['user_id'], '您与'.$result['data']['user_right']['nickname'].'达成'.$rankInfo['rank_name'].'关系，去查看', 'kkaudio://user_relation?user_id='.$result['data']['user_left']['user_id'], '去查看');
//                $this->msgService->sendUserWithUrlMsg($result['data']['user_right']['user_id'], '您与'.$result['data']['user_left']['nickname'].'达成'.$rankInfo['rank_name'].'关系，去查看', 'kkaudio://user_relation?user_id='.$result['data']['user_right']['user_id'], '去查看');
                $this->msgService->sendUserWithUrlMsg($result['data']['user_left']['user_id'], '您与'.$result['data']['user_right']['nickname'].'达成'.$rankInfo['rank_name'].'关系，', 'kkaudio://user_relation?user_id='.$result['data']['user_left']['user_id'], ' 去查看》》');
                $this->msgService->sendUserWithUrlMsg($result['data']['user_right']['user_id'], '您与'.$result['data']['user_left']['nickname'].'达成'.$rankInfo['rank_name'].'关系，', 'kkaudio://user_relation?user_id='.$result['data']['user_right']['user_id'], ' 去查看》》');
            }

            $this->roomModel->editRoomPaipaiLog($info['logId'], ['rank_id'=>intval($rankId), 'day'=>intval($day)]);

            //拍拍房通用消息
            $endTime = strtotime($info['created_at'])+$info['second_num'];
            $this->roomMsgService->roomPaiPaiAddTimeMsg($roomId, $endTime, 3, $result['data']);

            //删除缓存
            Redis::del($cacheKey);

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 获取当前热度最高的拍拍房
     */
    public function roomPaiPaiHotMax($userId)
    {
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        $now = time();
        do {
            $query = [
                "term" => [
                    "room_type.id" => '46',
                ],
            ];
            $list = $this->roomHotModel->queryRoomHotFromEs($query, 0, 1);
            if(empty($list)) {
                $code = Hint::PARAM_ERROR;
                $msg = '暂无开启的拍拍房间';
                break;
            }
            $data = [
                'room_id' => $list[0]['room_id'],
            ];

        } while (false);

        return compact('code', 'msg', 'data');
    }

    //隐藏房间
    public function hideRoom($roomId, $hideStatus){
        $code = Hint::SUCCESS;
        $data = [];
        $msg = '';
        do{
            if(empty($roomId)){
                $code = Hint::PARAM_ERROR;
                break;
            }
            if(!in_array($hideStatus, [0,1])){
                $code = Hint::PARAM_ERROR;
                break;
            }
            try{
                DB::beginTransaction();
                $res = $this->roomModel->chaneHideStatus($roomId, $hideStatus);
                if($res){
                    if($hideStatus == 1){
                        //清除热度排行
                        $this->roomHotModel->del($roomId);
                    }
                }
                Redis::del($this->redis_room_cache.$roomId);
                DB::commit();
            }catch(\Exception $e){
                DB::rollBack();
                $code = Hint::ERROR;
                write_log('hideRoom','ERROR 隐藏房间出错',['msg'=>$e->getMessage(),'roomId'=>$roomId]);
                break;
            }
        }while(false);
        return compact('code','data','msg');
    }
}
